home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pine / osdep / print < prev    next >
Text File  |  1996-05-21  |  10KB  |  399 lines

  1. /*======================================================================
  2.     print routines
  3.    
  4.     Functions having to do with printing on paper and forking of spoolers
  5.  
  6.     In general one calls open_printer() to start printing. One of
  7.     the little print functions to send a line or string, and then
  8.     call print_end() when complete. This takes care of forking off a spooler
  9.     and piping the stuff down it. No handles or anything here because there's
  10.     only one printer open at a time.
  11.  
  12.  ====*/
  13.  
  14.  
  15.  
  16. static char *trailer;  /* so both open and close_printer can see it */
  17.  
  18. /*----------------------------------------------------------------------
  19.        Open the printer
  20.  
  21.   Args: desc -- Description of item to print. Should have one trailing blank.
  22.  
  23.   Return value: < 0 is a failure.
  24.         0 a success.
  25.  
  26. This does most of the work of popen so we can save the standard output of the
  27. command we execute and send it back to the user.
  28.   ----*/
  29. int
  30. open_printer(desc)
  31.     char     *desc;
  32. {
  33.     char command[201], prompt[200];
  34.     int  cmd, rc, just_one;
  35.     char *p, *init, *nick;
  36.     char aname[100];
  37.     char *printer;
  38.     int     done = 0, i, lastprinter, cur_printer = 0;
  39.     HelpType help;
  40.     char   **list;
  41.     static ESCKEY_S ekey[] = {
  42.     {'y', 'y', "Y", "Yes"},
  43.     {'n', 'n', "N", "No"},
  44.     {ctrl('P'), 10, "^P", "Prev Printer"},
  45.     {ctrl('N'), 11, "^N", "Next Printer"},
  46.     {-2,   0,   NULL, NULL},
  47.     {'c', 'c', "C", "CustomPrint"},
  48.     {KEY_UP,    10, "", ""},
  49.     {KEY_DOWN,  11, "", ""},
  50.     {-1, 0, NULL, NULL}};
  51. #define PREV_KEY   2
  52. #define NEXT_KEY   3
  53. #define CUSTOM_KEY 5
  54. #define UP_KEY     6
  55. #define DOWN_KEY   7
  56.  
  57.     trailer      = NULL;
  58.     init         = NULL;
  59.     nick         = NULL;
  60.     command[200] = '\0';
  61.  
  62.     if(ps_global->VAR_PRINTER == NULL){
  63.         q_status_message(SM_ORDER | SM_DING, 3, 5,
  64.     "No printer has been chosen.  Use SETUP on main menu to make choice.");
  65.     return(-1);
  66.     }
  67.  
  68.     /* Is there just one print command available? */
  69.     just_one = (ps_global->printer_category!=3&&ps_global->printer_category!=2)
  70.            || (ps_global->printer_category == 2
  71.            && !(ps_global->VAR_STANDARD_PRINTER
  72.             && ps_global->VAR_STANDARD_PRINTER[0]
  73.             && ps_global->VAR_STANDARD_PRINTER[1]))
  74.            || (ps_global->printer_category == 3
  75.            && !(ps_global->VAR_PERSONAL_PRINT_COMMAND
  76.             && ps_global->VAR_PERSONAL_PRINT_COMMAND[0]
  77.             && ps_global->VAR_PERSONAL_PRINT_COMMAND[1]));
  78.  
  79.     if(F_ON(F_CUSTOM_PRINT, ps_global))
  80.       ekey[CUSTOM_KEY].ch = 'c'; /* turn this key on */
  81.     else
  82.       ekey[CUSTOM_KEY].ch = -2;  /* turn this key off */
  83.  
  84.     if(just_one){
  85.     ekey[PREV_KEY].ch = -2;  /* turn these keys off */
  86.     ekey[NEXT_KEY].ch = -2;
  87.     ekey[UP_KEY].ch   = -2;
  88.     ekey[DOWN_KEY].ch = -2;
  89.     }
  90.     else{
  91.     ekey[PREV_KEY].ch = ctrl('P'); /* turn these keys on */
  92.     ekey[NEXT_KEY].ch = ctrl('N');
  93.     ekey[UP_KEY].ch   = KEY_UP;
  94.     ekey[DOWN_KEY].ch = KEY_DOWN;
  95.     /*
  96.      * count how many printers in list and find the default in the list
  97.      */
  98.     if(ps_global->printer_category == 2)
  99.       list = ps_global->VAR_STANDARD_PRINTER;
  100.     else
  101.       list = ps_global->VAR_PERSONAL_PRINT_COMMAND;
  102.  
  103.     for(i = 0; list[i]; i++)
  104.       if(strcmp(ps_global->VAR_PRINTER, list[i]) == 0)
  105.         cur_printer = i;
  106.     
  107.     lastprinter = i - 1;
  108.     }
  109.  
  110.     help = NO_HELP;
  111.     ps_global->mangled_footer = 1;
  112.  
  113.     while(!done){
  114.     if(init)
  115.       fs_give((void **)&init);
  116.  
  117.     if(trailer)
  118.       fs_give((void **)&trailer);
  119.  
  120.     if(just_one)
  121.       printer = ps_global->VAR_PRINTER;
  122.     else
  123.       printer = list[cur_printer];
  124.  
  125.     parse_printer(printer, &nick, &p, &init, &trailer, NULL, NULL);
  126.     strncpy(command, p, 200);
  127.     fs_give((void **)&p);
  128.     sprintf(prompt, "Print %susing \"%s\" ? ", desc ? desc : "",
  129.         *nick ? nick : command);
  130.  
  131.     fs_give((void **)&nick);
  132.     
  133.     cmd = radio_buttons(prompt, -FOOTER_ROWS(ps_global),
  134.                  ekey, 'y', 'x', help, RB_NORM);
  135.     
  136.     switch(cmd){
  137.       case 'y':
  138.         q_status_message1(SM_ORDER, 0, 9,
  139.         "Printing with command \"%s\"", command);
  140.         done++;
  141.         break;
  142.  
  143.       case 10:
  144.         cur_printer = (cur_printer>0)
  145.                 ? (cur_printer-1)
  146.                 : lastprinter;
  147.         break;
  148.  
  149.       case 11:
  150.         cur_printer = (cur_printer<lastprinter)
  151.                 ? (cur_printer+1)
  152.                 : 0;
  153.         break;
  154.  
  155.       case 'n':
  156.       case 'x':
  157.         done++;
  158.         break;
  159.  
  160.       case 'c':
  161.         done++;
  162.         break;
  163.  
  164.       default:
  165.         break;
  166.     }
  167.     }
  168.  
  169.     if(cmd == 'c'){
  170.     if(init)
  171.       fs_give((void **)&init);
  172.  
  173.     if(trailer)
  174.       fs_give((void **)&trailer);
  175.  
  176.     sprintf(prompt, "Enter custom command : ");
  177.     command[0] = '\0';
  178.     rc = 1;
  179.     while(rc){
  180.         rc = optionally_enter(command, -FOOTER_ROWS(ps_global), 0,
  181.         200, 1, 0, prompt, NULL, NO_HELP, 0);
  182.         
  183.         if(rc == 1){
  184.         cmd = 'x';
  185.         rc = 0;
  186.         }
  187.         else if(rc == 3)
  188.           q_status_message(SM_ORDER, 0, 3, "No help available");
  189.         else if(rc == 0){
  190.         removing_trailing_white_space(command);
  191.         removing_leading_white_space(command);
  192.         q_status_message1(SM_ORDER, 0, 9,
  193.             "Printing with command \"%s\"", command);
  194.         }
  195.     }
  196.     }
  197.  
  198.     if(cmd == 'x' || cmd == 'n'){
  199.     q_status_message(SM_ORDER, 0, 2, "Print cancelled");
  200.     if(init)
  201.       fs_give((void **)&init);
  202.  
  203.     if(trailer)
  204.       fs_give((void **)&trailer);
  205.  
  206.     return(-1);
  207.     }
  208.  
  209.     display_message('x');
  210.  
  211.     ps_global->print = (PRINT_S *)fs_get(sizeof(PRINT_S));
  212.     memset(ps_global->print, 0, sizeof(PRINT_S));
  213.  
  214.     strcat(strcpy(aname, ANSI_PRINTER), "-no-formfeed");
  215.     if(strucmp(command, ANSI_PRINTER) == 0
  216.        || strucmp(command, aname) == 0){
  217.         /*----------- Printer attached to ansi device ---------*/
  218.         q_status_message(SM_ORDER, 0, 9,
  219.         "Printing to attached desktop printer...");
  220.         display_message('x');
  221.     xonxoff_proc(1);            /* make sure XON/XOFF used */
  222.     crlf_proc(1);                /* AND LF->CR xlation */
  223.         fputs("\033[5i", stdout);
  224.         ps_global->print->fp = stdout;
  225.         if(strucmp(command, ANSI_PRINTER) == 0){
  226.         /* put formfeed at the end of the trailer string */
  227.         if(trailer){
  228.         int len = strlen(trailer);
  229.  
  230.         fs_resize((void **)&trailer, len+2);
  231.         trailer[len] = '\f';
  232.         trailer[len+1] = '\0';
  233.         }
  234.         else
  235.           trailer = cpystr("\f");
  236.     }
  237.     }
  238.     else{
  239.         /*----------- Print by forking off a UNIX command ------------*/
  240.         dprint(4, (debugfile, "Printing using command \"%s\"\n", command));
  241.     ps_global->print->result = temp_nam(NULL, "pine_prt");
  242.     if(ps_global->print->pipe = open_system_pipe(command,
  243.                      &ps_global->print->result, NULL,
  244.                      PIPE_WRITE | PIPE_STDERR)){
  245.         ps_global->print->fp = ps_global->print->pipe->out.f;
  246.     }
  247.     else{
  248.         fs_give((void **)&ps_global->print->result);
  249.             q_status_message1(SM_ORDER | SM_DING, 3, 4,
  250.                   "Error opening printer: %s",
  251.                               error_description(errno));
  252.             dprint(2, (debugfile, "Error popening printer \"%s\"\n",
  253.                       error_description(errno)));
  254.         if(init)
  255.           fs_give((void **)&init);
  256.  
  257.         if(trailer)
  258.           fs_give((void **)&trailer);
  259.         
  260.         return(-1);
  261.         }
  262.     }
  263.  
  264.     ps_global->print->err = 0;
  265.     if(init){
  266.     if(*init)
  267.       fputs(init, ps_global->print->fp);
  268.  
  269.     fs_give((void **)&init);
  270.     }
  271.  
  272.     return(0);
  273. }
  274.  
  275.  
  276.  
  277. /*----------------------------------------------------------------------
  278.      Close printer
  279.   
  280.   If we're piping to a spooler close down the pipe and wait for the process
  281. to finish. If we're sending to an attached printer send the escape sequence.
  282. Also let the user know the result of the print
  283.  ----*/
  284. void
  285. close_printer()
  286. {
  287.     if(trailer){
  288.     if(*trailer)
  289.       fputs(trailer, ps_global->print->fp);
  290.  
  291.     fs_give((void **)&trailer);
  292.     }
  293.  
  294.     if(ps_global->print->fp == stdout) {
  295.         fputs("\033[4i", stdout);
  296.         fflush(stdout);
  297.     xonxoff_proc(0);            /* turn off XON/XOFF */
  298.     crlf_proc(0);                /* turn off CF->LF xlantion */
  299.     } else {
  300.     (void) close_system_pipe(&ps_global->print->pipe);
  301.     display_output_file(ps_global->print->result, "PRINT", NULL);
  302.     fs_give((void **)&ps_global->print->result);
  303.     }
  304.  
  305.     fs_give((void **)&ps_global->print);
  306.  
  307.     q_status_message(SM_ASYNC, 0, 3, "Print command completed");
  308.     display_message('x');
  309. }
  310.  
  311.  
  312.  
  313. /*----------------------------------------------------------------------
  314.      Print a single character
  315.  
  316.   Args: c -- char to print
  317.   Returns: 1 on success, 0 on ps_global->print->err
  318.  ----*/
  319. int
  320. print_char(c)
  321.     int c;
  322. {
  323.     if(!ps_global->print->err && putc(c, ps_global->print->fp) == EOF)
  324.       ps_global->print->err = 1;
  325.  
  326.     return(!ps_global->print->err);
  327. }
  328.  
  329.  
  330.  
  331. /*----------------------------------------------------------------------
  332.      Send a line of text to the printer
  333.  
  334.   Args:  line -- Text to print
  335.  
  336.   ----*/
  337.     
  338. void
  339. print_text(line)
  340.     char *line;
  341. {
  342.     if(!ps_global->print->err && fputs(line, ps_global->print->fp) == EOF)
  343.       ps_global->print->err = 1;
  344. }
  345.  
  346.  
  347.  
  348. /*----------------------------------------------------------------------
  349.       printf style formatting with one arg for printer
  350.  
  351.  Args: line -- The printf control string
  352.        a1   -- The 1st argument for printf
  353.  ----*/
  354. void
  355. print_text1(line, a1)
  356.     char *line, *a1;
  357. {
  358.     if(!ps_global->print->err
  359.        && fprintf(ps_global->print->fp, line, a1) < 0)
  360.       ps_global->print->err = 1;
  361. }
  362.  
  363.  
  364.  
  365. /*----------------------------------------------------------------------
  366.       printf style formatting with one arg for printer
  367.  
  368.  Args: line -- The printf control string
  369.        a1   -- The 1st argument for printf
  370.        a2   -- The 2nd argument for printf
  371.  ----*/
  372. void
  373. print_text2(line, a1, a2)
  374.     char *line, *a1, *a2;
  375. {
  376.     if(!ps_global->print->err
  377.        && fprintf(ps_global->print->fp, line, a1, a2) < 0)
  378.       ps_global->print->err = 1;
  379. }
  380.  
  381.  
  382.  
  383. /*----------------------------------------------------------------------
  384.       printf style formatting with one arg for printer
  385.  
  386.  Args: line -- The printf control string
  387.        a1   -- The 1st argument for printf
  388.        a2   -- The 2nd argument for printf
  389.        a3   -- The 3rd argument for printf
  390.  ----*/
  391. void
  392. print_text3(line, a1, a2, a3)
  393.     char *line, *a1, *a2, *a3;
  394. {
  395.     if(!ps_global->print->err
  396.        && fprintf(ps_global->print->fp, line, a1, a2, a3) < 0)
  397.       ps_global->print->err = 1;
  398. }
  399.